﻿using System.Text.Json.Serialization;
using BCore.Identity.Users.Caching;
using Core.Caching;
using Core.Domain.Entities;
using Core.Domain.Enums;
using Core.Helpers;
using Core.Identity.Common.Interfaces.Common.Interfaces;
using Core.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;


namespace Core.Identity.Users.Features.Commands.Update;

#nullable disable

/// <summary>
/// 修改用户信息
/// </summary>
public class UpdateUserCommand : ICacheInvalidatorRequest<Result<bool>>
{
    public Guid UserId { get; set; }
    /// <summary>
    /// 电子邮箱
    /// </summary>
    public string Email { get; set; }
    /// <summary>
    /// 昵称
    /// </summary>
    public required string Nickname { get; set; }
    /// <summary>
    /// 手机号码
    /// </summary>
    public required string PhoneNumber { get; set; }
    /// <summary>
    /// 性别
    /// </summary>
    public GenderType Gender { get; set; }

    /// <summary>
    /// 组织机构
    /// </summary>
    public Guid? OrganizationId { get; set; }

    /// <summary>
    /// 设置描述
    /// </summary>
    public string Description { get; set; }

    [JsonIgnore]
    public IEnumerable<string> Tags => UsersCacheKey.Tags;
}
public class UpdateUserCommandHandler(IIdentityDbContext dbContext) : IRequestHandler<UpdateUserCommand, Result<bool>>
{

    public async Task<Result<bool>> Handle(UpdateUserCommand request, CancellationToken cancellationToken)
    {
        var user = await dbContext.Users.FindAsync(request.UserId, cancellationToken);
        ExceptionHelper.ThrowIfNull(user, "数据不存在");

        if (request.OrganizationId != null && request.OrganizationId != Guid.Empty)
        {
            var organization = await dbContext.Organizations
                .FirstOrDefaultAsync(x => x.Id == request.OrganizationId, cancellationToken);
            ExceptionHelper.ThrowIfNull(organization, "组织不存在");

            var userOrganizations = await dbContext.UserOrganizations
                .Where(x => x.UserId == request.UserId).ToListAsync(cancellationToken);
            if (userOrganizations != null && userOrganizations.Any())
            {
                dbContext.UserOrganizations.RemoveRange(userOrganizations);
            }

            var userOrganization = new UserOrganization(user, organization, OrganizationPosition.Member);
            await dbContext.UserOrganizations.AddAsync(userOrganization);
        }

        if (user.Email != request.Email)
        {
            var emailExist = await dbContext.Users
                .AnyAsync(x => x.Email == request.Email && x.Id != request.UserId, cancellationToken);
            ExceptionHelper.ThrowIfTrue(emailExist, "邮箱已被占用");
        }

        user.SetEmail(request.Email);
        user.ChangeNickname(request.Nickname);
        user.SetPhoneNumber(request.PhoneNumber ?? "", false);
        user.SetGender(request.Gender);
        user.SetDescription(request.Description);

        dbContext.Users.Update(user);


        var result = await dbContext.SaveChangesAsync(cancellationToken) > 0;
        return await Result<bool>.SucceedAsync(result, result, ["修改失败"]);
    }
}
